package com.atguigu.classroom.live.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.classroom.CourseClient.CourseFeignClient;
import com.atguigu.classroom.exception.ClassroomException;
import com.atguigu.classroom.live.mapper.LiveCourseAccountMapper;
import com.atguigu.classroom.live.mapper.LiveCourseDescriptionMapper;
import com.atguigu.classroom.live.mtcloud.CommonResult;
import com.atguigu.classroom.live.mtcloud.MTCloud;
import com.atguigu.classroom.model.live.LiveCourse;
import com.atguigu.classroom.live.mapper.LiveCourseMapper;
import com.atguigu.classroom.live.service.LiveCourseService;
import com.atguigu.classroom.model.live.LiveCourseAccount;
import com.atguigu.classroom.model.live.LiveCourseDescription;
import com.atguigu.classroom.model.user.UserInfo;
import com.atguigu.classroom.model.vod.Teacher;
import com.atguigu.classroom.userClient.UserInfoFeignClient;
import com.atguigu.classroom.utils.DateUtil;
import com.atguigu.classroom.vo.live.LiveCourseFormVo;
import com.atguigu.classroom.vo.live.LiveCourseVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.alibaba.fastjson.JSONObject;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 直播课程表 服务实现类
 * </p>
 *
 * @author atguigu
 * @since 2022-07-26
 */
@Service
public class LiveCourseServiceImpl extends ServiceImpl<LiveCourseMapper, LiveCourse> implements LiveCourseService {
    @Autowired
    private LiveCourseMapper liveCourseMapper;
    @Autowired
    private CourseFeignClient courseFeignClient;
    @Autowired
    private MTCloud mtCloud;
    @Autowired
    private LiveCourseDescriptionMapper liveCourseDescriptionMapper;
    @Autowired
    private LiveCourseAccountMapper liveCourseAccountMapper;
    @Autowired
    private UserInfoFeignClient userInfoFeignClient;
    @Override
    public Page<LiveCourse> selectPage(int page, int limit) {
        Page<LiveCourse> liveCoursePage=new Page<>(page,limit);
        liveCourseMapper.selectPage(liveCoursePage,null);//sql-1:获取基本信息
        List<Long> teacherIds=liveCoursePage.getRecords().stream().map(liveCourse -> {
            Long teacherId=liveCourse.getTeacherId();
            return teacherId;
        }).collect(Collectors.toList());
        List<Teacher> teachers = courseFeignClient.getTeachers(teacherIds);//sql-2:获取讲师信息（远程调用）
        Map<Long,Teacher> teacherMap=new HashMap<>(teachers.size());
        teachers.stream().map(teacher -> {
            teacherMap.put(teacher.getId(),teacher);
            return null;
        }).collect(Collectors.toList());
        List<LiveCourse> liveCourseList=liveCoursePage.getRecords().stream().map(liveCourse -> {
            LiveCourse newLiveCourse=new LiveCourse();
            BeanUtils.copyProperties(liveCourse,newLiveCourse);
            if(teacherMap.containsKey(liveCourse.getTeacherId())){
                newLiveCourse.getParam().put("teacherName",teacherMap.get(liveCourse.getTeacherId()).getName());
                newLiveCourse.getParam().put("teacherLevel",teacherMap.get(liveCourse.getTeacherId()).getLevel());
            }
            return newLiveCourse;
        }).collect(Collectors.toList());
        liveCoursePage.setRecords(liveCourseList);
        return liveCoursePage;
    }

    @Override
    @Transactional
    public void saveLiveCourse(LiveCourseFormVo liveCourseFormVo) {
        LiveCourse liveCourse=new LiveCourse();
        BeanUtils.copyProperties(liveCourseFormVo,liveCourse);
        Teacher teacher=courseFeignClient.getTeachers(
                Collections.singletonList(liveCourseFormVo.getTeacherId())).get(0);
        HashMap<Object, Object> options = new HashMap<>();
        options.put("scenes", 2);//直播类型:1教育直播(默认)，2生活直播。说明:根据平台开通的直播类型填写
        options.put("password", liveCourseFormVo.getPassword());
        try {//添加直播到欢拓云并返回结果
            String res = mtCloud.courseAdd(liveCourse.getCourseName(),
                teacher.getId().toString(),
                new DateTime(liveCourse.getStartTime()).toString("yyyy-MM-dd HH:mm:ss"),
                new DateTime(liveCourse.getEndTime()).toString("yyyy-MM-dd HH:mm:ss"),
                teacher.getName(),
                teacher.getIntro(),
                options);
            //对返回结果进行解析并进行判断
            CommonResult<JSONObject> commonResult= JSON.parseObject(res,CommonResult.class);
            if(Integer.parseInt(commonResult.getCode())==MTCloud.CODE_SUCCESS){
                //添加直播基本信息--live_course表
                Long course_id=commonResult.getData().getLong("course_id");//直播课程id
                liveCourse.setCourseId(course_id);
                liveCourseMapper.insert(liveCourse);//sql-1
                //添加直播描述信息--live_course_description表
                LiveCourseDescription liveCourseDescription=new LiveCourseDescription();
                liveCourseDescription.setDescription(liveCourseFormVo.getDescription());
                liveCourseDescription.setLiveCourseId(liveCourse.getId());
                liveCourseDescriptionMapper.insert(liveCourseDescription);//sql-2
                //添加直播账号信息--live_course_account表
                LiveCourseAccount liveCourseAccount = new LiveCourseAccount();
                liveCourseAccount.setLiveCourseId(liveCourse.getId());
                liveCourseAccount.setZhuboAccount(commonResult.getData().getString("bid"));
                liveCourseAccount.setZhuboPassword(liveCourseFormVo.getPassword());
                liveCourseAccount.setAdminKey(commonResult.getData().getString("admin_key"));
                liveCourseAccount.setUserKey(commonResult.getData().getString("user_key"));
                liveCourseAccount.setZhuboKey(commonResult.getData().getString("zhubo_key"));
                liveCourseAccountMapper.insert(liveCourseAccount);//sql-3
            }else {
                throw new ClassroomException(20001,"直播课程添加失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    @Transactional
    public void deleteLiveCourse(Long id) {
        LiveCourse liveCourse = liveCourseMapper.selectById(id);
        if(liveCourse!=null){
            try {//先CourseId删除欢拓云里的直播课程信息
                mtCloud.courseDelete(String.valueOf(liveCourse.getCourseId()));
                liveCourseMapper.deleteById(id);//sql-1:删除直播基本信息
                LambdaQueryWrapper<LiveCourseDescription> liveCourseDescriptionQueryWrapper=new LambdaQueryWrapper<>();
                LambdaQueryWrapper<LiveCourseAccount> liveCourseAccountQueryWrapper=new LambdaQueryWrapper<>();
                liveCourseDescriptionQueryWrapper.eq(LiveCourseDescription::getLiveCourseId,id);
                liveCourseAccountQueryWrapper.eq(LiveCourseAccount::getLiveCourseId,id);
                liveCourseDescriptionMapper.deleteById(liveCourseDescriptionQueryWrapper);//sql-2:删除直播描述信息
                liveCourseAccountMapper.delete(liveCourseAccountQueryWrapper);//sql-3:删除直播账号信息
            } catch (Exception e) {
                e.printStackTrace();
                throw new ClassroomException(20001,"欢拓云直播课程删除失败");
            }
        }
    }

    @Override
    public LiveCourseFormVo getLiveCourseFormVo(Long id) {
        LiveCourse liveCourse = liveCourseMapper.selectById(id);//sql-1:查询课程基本信息
        LambdaQueryWrapper<LiveCourseDescription> liveCourseDescriptionQueryWrapper=new LambdaQueryWrapper<>();
        liveCourseDescriptionQueryWrapper.eq(LiveCourseDescription::getLiveCourseId,id);
        LiveCourseDescription liveCourseDescription = liveCourseDescriptionMapper.selectOne(liveCourseDescriptionQueryWrapper);
        //sql-2:查询直播描述信息
        LambdaQueryWrapper<LiveCourseAccount> liveCourseAccountQueryWrapper=new LambdaQueryWrapper<>();
        liveCourseAccountQueryWrapper.eq(LiveCourseAccount::getLiveCourseId,id);
        LiveCourseAccount liveCourseAccount = liveCourseAccountMapper.selectOne(liveCourseAccountQueryWrapper);
        //sql-3:查询直播账号信息
        LiveCourseFormVo liveCourseFormVo=new LiveCourseFormVo();
        BeanUtils.copyProperties(liveCourse,liveCourseFormVo);//主体消息
        liveCourseFormVo.setDescription(liveCourseDescription.getDescription());//描述
        liveCourseFormVo.setPassword(liveCourseAccount.getZhuboPassword());//密码
        return liveCourseFormVo;
    }

    @Override
    @Transactional
    public void updateLiveCourseFromVoById(LiveCourseFormVo liveCourseFromVo) {
        LiveCourse liveCourse=new LiveCourse();
        BeanUtils.copyProperties(liveCourseFromVo,liveCourse);
        Teacher teacher = courseFeignClient.getTeachers(//sql-1:查询讲师信息
                Collections.singletonList(liveCourse.getTeacherId())).get(0);
        try {
            String res = mtCloud.courseUpdate(liveCourse.getCourseId().toString(),
                teacher.getId().toString(),
                liveCourse.getCourseName(),
                new DateTime(liveCourse.getStartTime()).toString("yyyy-MM-dd HH:mm:ss"),
                new DateTime(liveCourse.getEndTime()).toString("yyyy-MM-dd HH:mm:ss"),
                teacher.getName(),
                teacher.getIntro(),
                new HashMap<>());
            //对返回结果进行解析并进行判断
            CommonResult<JSONObject> commonResult= JSON.parseObject(res,CommonResult.class);
            if(Integer.parseInt(commonResult.getCode())==MTCloud.CODE_SUCCESS){
                JSONObject data = commonResult.getData();
                liveCourse.setCourseId(data.getLong("course_id"));
                liveCourseMapper.updateById(liveCourse);//sql-1:更新课程基本信息
                LambdaQueryWrapper<LiveCourseDescription> descriptionQueryWrapper=new LambdaQueryWrapper<>();
                descriptionQueryWrapper.eq(LiveCourseDescription::getLiveCourseId,liveCourse.getId());
                LiveCourseDescription liveCourseDescription=new LiveCourseDescription();
                liveCourseDescription.setDescription(liveCourseFromVo.getDescription());
                liveCourseDescriptionMapper.update(liveCourseDescription,descriptionQueryWrapper);
                //sql-2:更新直播课程描述信息
                LambdaQueryWrapper<LiveCourseAccount> liveCourseAccountQueryWrapper=new LambdaQueryWrapper<>();
                liveCourseAccountQueryWrapper.eq(LiveCourseAccount::getLiveCourseId,liveCourse.getId());
                LiveCourseAccount liveCourseAccount = new LiveCourseAccount();
                liveCourseAccount.setZhuboAccount(commonResult.getData().getString("bid"));
                liveCourseAccount.setZhuboPassword(liveCourseFromVo.getPassword());
                liveCourseAccount.setAdminKey(commonResult.getData().getString("admin_key"));
                liveCourseAccount.setUserKey(commonResult.getData().getString("user_key"));
                liveCourseAccount.setZhuboKey(commonResult.getData().getString("zhubo_key"));
                liveCourseAccountMapper.update(liveCourseAccount,liveCourseAccountQueryWrapper);
                //sql-3:更新直播课程账号信息
            }else {
                throw new ClassroomException(20001,"欢拓云直播课程修改失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new ClassroomException(20001,"欢拓云直播课程修改失败");
        }
    }

    @Override
    public List<LiveCourseVo> findLatelyList() {
        Page<LiveCourse> liveCoursePage=new Page<>(1,5);
        LambdaQueryWrapper<LiveCourse> liveCourseQueryWrapper=new LambdaQueryWrapper<>();
        liveCourseQueryWrapper.ge(LiveCourse::getStartTime,new Date())
                .orderByAsc(LiveCourse::getStartTime);
        liveCourseMapper.selectPage(liveCoursePage,liveCourseQueryWrapper);
        //sql-1:查询最近课程的基本信息
        if(liveCoursePage.getRecords().size()==0){
            return new ArrayList<>();
        }
        List<Long> teacherIds=new ArrayList<>(liveCoursePage.getRecords().size());
        List<LiveCourseVo> liveCourseVos=liveCoursePage.getRecords().stream().map(liveCourse -> {
            LiveCourseVo liveCourseVo=new LiveCourseVo();
            BeanUtils.copyProperties(liveCourse,liveCourseVo);
            teacherIds.add(liveCourse.getTeacherId());
            liveCourseVo.setStartTimeString(new DateTime(liveCourseVo.getStartTime()).toString("yyyy年MM月dd HH:mm"));
            liveCourseVo.setEndTimeString(new DateTime(liveCourseVo.getEndTime()).toString("HH:mm"));
            liveCourseVo.setLiveStatus(this.getLiveStatus(liveCourseVo));
            return liveCourseVo;
        }).collect(Collectors.toList());
        List<Teacher> teachers = courseFeignClient.getTeachers(teacherIds);
        //sql-2:查询最近课程的讲师信息(远程调用)
        Map<Long,Teacher> teacherMap=new HashMap<>(teachers.size());
        for(Teacher teacher:teachers){
            teacherMap.put(teacher.getId(),teacher);
        }
        List<LiveCourseVo> newLiveCourseVos=liveCourseVos.stream().map(liveCourseVo -> {
            LiveCourseVo myLiveCourseVo=new LiveCourseVo();
            BeanUtils.copyProperties(liveCourseVo,myLiveCourseVo);
            myLiveCourseVo.setTeacher(teacherMap.get(myLiveCourseVo.getTeacherId()));
            return myLiveCourseVo;
        }).collect(Collectors.toList());
        return newLiveCourseVos;
    }
    /**直播状态 0：未开始 1：直播中 2：直播结束
     */
    private int getLiveStatus(LiveCourse liveCourse) {
        int liveStatus = 0;
        Date curTime = new Date();
        if(DateUtil.dateCompare(curTime, liveCourse.getStartTime())) {
            liveStatus = 0;
        } else if(DateUtil.dateCompare(curTime, liveCourse.getEndTime())) {
            liveStatus = 1;
        } else {
            liveStatus = 2;
        }
        return liveStatus;
    }
    @Override
    public JSONObject getAccessToken(Long id, Long userId) {
        //根据课程id获取直播课程信息；
        LiveCourse liveCourse = liveCourseMapper.selectById(id);
        //根据用户id获取用户信息；
        UserInfo userInfo = userInfoFeignClient.getByIds(Collections.singletonList(userId)).get(0);
        //封装需要的参数
        /*
         *  course_id :课程ID
         *  uid       :用户唯一ID
         *  nickname  :用户昵称
         *  role      :用户角色，枚举见:ROLE 定义
         *  expire    :有效期,默认:3600(单位:秒)
         *  options   :可选项，包括:gender:枚举见上面GENDER定义,avatar:头像地址
         */
        try {
            String res = mtCloud.courseAccess(
                    liveCourse.getCourseId().toString(),
                    userId.toString(),
                    userInfo.getName(),
                    MTCloud.ROLE_USER,
                    3700,
                    new HashMap<Object, Object>()
            );
            CommonResult<JSONObject> commonResult = JSON.parseObject(res, CommonResult.class);
            if(Integer.parseInt(commonResult.getCode()) == MTCloud.CODE_SUCCESS) {
                JSONObject object = commonResult.getData();
                System.out.println("得到的access是:"+object.getString("access_token"));
                return object;
            } else {
                throw new ClassroomException(20001,"获取失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new ClassroomException(20001,"获取失败");
        }
    }
}
